#ifndef _HJ212_MSG_H
#define _HJ212_MSG_H

#include <stdint.h>
#include <time.h>

#include "hj212_client_def.h"

/* HJ212国标协议命令 */
enum hj212_cmd
{
    /* 初始化命令 */
    HJ_CMD_SET_TIMEOUT_RECOUNT_1000 = 1000, ///<设置超时时间及重发次数

    /* 参数命令 */
    HJ_CMD_GET_SYS_DT_1011 = 1011,       ///<提取现场机系统时间,上传现场机时间
    HJ_CMD_SET_SYS_DT_1012 = 1012,       ///<设置现场机时间
    HJ_CMD_SYS_DT_CALIB_1013 = 1013,     ///<现场机时间校准请求
    HJ_CMD_GET_RTD_INTERVAL_1061 = 1061, ///<提取实时数据间隔,上传实时数据间隔
    HJ_CMD_SET_RTD_INTERVAL_1062 = 1062, ///<设置实时数据间隔
    HJ_CMD_GET_MIN_INTERVAL_1063 = 1063, ///<提取分钟数据间隔,上传分钟数据间隔
    HJ_CMD_SET_MIN_INTERVAL_1064 = 1064, ///<设置分钟数据间隔
    HJ_CND_SET_SYS_PW_1072 = 1072,       ///<设置现场机密码

    /* 数据命令 */
    HJ_CMD_RTD_DATA_2011 = 2011,  ///<实时数据
    HJ_CMD_DEV_STATE_2021 = 2021, ///<设备状态
    HJ_CMD_MIN_DATA_2051 = 2051,  ///<分钟数据
    HJ_CMD_HOUR_DATA_2061 = 2061, ///<小时数据
    HJ_CMD_DAY_DATA_2031 = 2031,  ///<日数据

    /* 控制命令 */
    HJ_CMD_CALIB_3011 = 3011,        ///<零点校准量程校准
    HJ_CMD_IMMED_SMP_3012 = 3012,    ///<即时作样
    HJ_CMD_CLEAN_3013 = 3013,        ///<启动清洗/反吹
    HJ_CMD_COMP_SMP_3014 = 3014,     ///<比对采样
    HJ_CMD_OVERP_SMP_3015 = 3015,    ///<超标留样,上传超标留样信息
    HJ_CMD_SET_SMPCYCLE_3016 = 3016, ///<设置采样时间周期
    HJ_CMD_GET_SMPCYCLE_3017 = 3017, ///<提取采样时间周期,上传采样时间周期
    HJ_CMD_GET_SMPTIME_3018 = 3018,  ///<提取出样时间,上传出样时间
    HJ_CMD_GET_UNIQUEID_3019 = 3019, ///<提取设备唯一标识
    HJ_CMD_GET_INFO_3020 = 3020,     ///<提取现场机信息,上传现场机信息
    HJ_CMD_SET_INFO_3021 = 3021,     ///<设置现场机参数

    /* 交互命令 */
    HJ_CMD_GET_QNRTN_9011 = 9011,   ///<请求应答
    HJ_CMD_GET_EXERTN_9012 = 9012,  ///<执行结果
    HJ_CMD_GET_NOTERTN_9013 = 9013, ///<通知应答
    HJ_CMD_GET_DATARTN_9014 = 9014, ///<数据应答
};

enum hj212_flag
{
    HJ_FLAG_HJ212_2005 = 0 << 2,    // 05协议
    HJ_FLAG_HJ212_2017 = 1 << 2,    // 17协议
    HJ_FLAG_NEED_RESPONSE = 1 << 0, // 需要响应
    HJ_FLAG_NO_RESPONSE = 0 << 0,   // 不需要响应
    HJ_FLAG_PACK_PNUM = 1 << 1,     // 数据包中带包号
    HJ_FLAG_NO_PACK_PNUM = 0 << 1,  // 数据包中不带包号
};

int hj212_datamsg_item_maxnum_per_package(int type);
int hj212_datamsg_typesize(int type);
int hj212_datamsg_init(struct hj212_datamsg *msg, int type, void *mempool, int memsize);
int hj212_datamsg_pack(struct hj212_datamsg *msg, int protocol, struct timeval precise_time, int item_maxlen, char *buffer, int len);
int hj212_datamsg_cn(int type);
const char *hj212_datamsg_cn_to_name(int cn);
int hj212_datamsg_response_cn(int type);
int hj212_datamsg_cn_to_type(int cn);

int hj212_response_is_idle(struct hj212_response *response);
void hj212_response_init(struct hj212_response *response,
                         hj212_response_match_t match, void *match_param,
                         hj212_response_timeout_t timeout_handle, void *timeout_param);
void hj212_response_register(struct hj212_client *client, struct hj212_response *response, int timeout);
void hj212_response_register_default(struct hj212_client *client, struct hj212_response *response, int timeout, int cn, const char *qn);
void hj212_response_unregister(struct hj212_response *response);

void hj212_pack_local(struct hj212_client *client,
                      char *buffer, int bufferlen,
                      const char *qn, const char *syscode, int cn, int isresponse,
                      struct hj212_msg *result,
                      const char *format, ...);
void hj212_pack_local_head(struct hj212_client *client,
                           char *buffer, int bufferlen,
                           const char *qn, const char *st, int cn, int isresponse,
                           struct hj212_msg *result);
int hj212_send_local_pack(struct hj212_client *client,
                          const char *qn, const char *syscode, int cn, int isresponse,
                          struct hj212_msg *result,
                          const char *format, ...);
#endif
